package edu.westga.sketchit2009cs.network;

/**
 * This is the ChatClient which acts like a JPanel, but connects to
 * a chat server, so other players will be able to chat with each other.
 */


import java.awt.*;
import java.awt.event.*;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import edu.westga.sketchit2009cs.gui.Sketchit2009csMainFrame;

import java.net.Socket;

public class ChatClient extends JPanel implements ActionListener, Runnable, KeyListener {

    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private final String ERROR_MESSAGE_STRING_VALUE = "The server does not exist, or there is a problem with your internet connection.";
	private final String CONNECTION_ERROR_STRING_VALUE = "Connection Error";
	private final String OPEN_BRACKET_STRING_VALUE = "[";
	private final String CLOSE_BRACKET_STRING_VALUE = "]: ";
	private final String HAS_JOINED_STRING_VALUE = " has joined";
	private final String NEWLINE_STRING_VALUE = "\n";
	private final String NULL_STRING_VALUE = "";

	private String screenName;

    // GUI stuff
    private JTextArea enteredText;
    private JTextField typedText;
	private JScrollPane chatScroll;
	private JPanel scoreChatPanel;

    // socket for connection to chat server
    private Socket socket;

    // for writing to and reading from the server
    private Out out;
    private In in;
    
    /**
     * The constructor of the ChatClient
     * Requires: a ChatServer to exist
     * 
     * Ensures: that the chat client will connect to a running chat server
     * 
     * @param screenName
     * @param hostName
     * @param portNumber
     */
    public ChatClient(String screenName, String hostName, int portNumber) {

        // connect to server
        try {
            socket = new Socket(hostName, portNumber);
            out    = new Out(socket);
            in     = new In(socket);
        }
        
        catch (Exception ex) 
        { 
			JDialog errorDialog = new JDialog();
			JOptionPane
					.showMessageDialog(
							errorDialog,
							ERROR_MESSAGE_STRING_VALUE,
							CONNECTION_ERROR_STRING_VALUE, 1);
			Sketchit2009csMainFrame.ResetMainWindow();
			return;
         }
        
        this.screenName = screenName;
        
		this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		
		this.setMaximumSize(new Dimension(300, 350));
        
        this.scoreChatPanel = new JPanel();
        
		this.scoreChatPanel.setMaximumSize(new Dimension(300, 200));
        
		this.enteredText = new JTextArea();
		this.enteredText.setMaximumSize(new Dimension(300, 300));
		this.enteredText.setEditable(false);
		this.scoreChatPanel.setLayout(new BoxLayout(scoreChatPanel, BoxLayout.Y_AXIS));
		this.chatScroll = new JScrollPane(enteredText);
		
		this.scoreChatPanel.add(Box.createRigidArea(new Dimension(20, 20)));
		this.typedText = new JTextField();
		this.scoreChatPanel.add(this.typedText);
		this.typedText.addKeyListener(this);
		this.typedText.setMaximumSize(new Dimension(300, 20));
		scoreChatPanel.add(chatScroll);
		scoreChatPanel.add(typedText);
		this.add(scoreChatPanel);
		this.setBackground(Color.LIGHT_GRAY);
		this.scoreChatPanel.setBackground(Color.LIGHT_GRAY);

    }

    // process TextField after user hits Enter
    public void actionPerformed(ActionEvent e) {
        out.println(OPEN_BRACKET_STRING_VALUE + screenName + CLOSE_BRACKET_STRING_VALUE + typedText.getText());
        typedText.setText("");
        typedText.requestFocusInWindow();
    }

    // listen to socket and print everything that server broadcasts
    private void listen() {
        String s;  
        out.println(screenName + HAS_JOINED_STRING_VALUE);

        while ((s = in.readLine()) != null) {
            enteredText.insert(s + NEWLINE_STRING_VALUE, enteredText.getText().length());
            enteredText.setCaretPosition(enteredText.getText().length());
        }
        out.close();
        in.close();
        try                 { socket.close();      }
        catch (Exception e) { e.printStackTrace(); }
    }
    
    /**
     * This is the chat box key press event so that users will be able to enter
     * chat
     */
	public void keyPressed(KeyEvent e) {

		if (e.getKeyCode() == KeyEvent.VK_ENTER
				&& !(this.typedText.getText().equals(NULL_STRING_VALUE))) {
			this.enteredText.setCaretPosition(this.enteredText.getRows());
	        out.println(OPEN_BRACKET_STRING_VALUE + screenName + CLOSE_BRACKET_STRING_VALUE + typedText.getText());        
			//this.enteredText.append(this.typedText.getText() + "\n");
			this.typedText.setText(NULL_STRING_VALUE);
			scrollPaneToBottom();

		}
	}

	//Automatically scrolls the pane to bottom
	private void scrollPaneToBottom() {

		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				chatScroll.getVerticalScrollBar().setValue(
				chatScroll.getVerticalScrollBar().getMaximum());
			}
		});
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}
	
	/**
	 * the runnable method that runs this class.
	 */
	@Override
	public void run() {
		try{
		this.listen();
		}
		catch(Exception e){
			//this was put here to remove non programming ending exception thread
		}
	}
}